//
// Created by xinrong.qian on 2025/4/15.
//

// 测试 GetGrayScaleArray 方法
#include "processor/CardProcessor.hpp"
#include "processor/CardPickProcessor.h"
#include "processor/CardParamPickProcessor.h"
#include <gtest/gtest.h>

#include <opencv2/opencv.hpp>
#include <vector>
#include <ZXing/ReadBarcode.h>

#define RED_TEXT(msg) "\033[31m" msg "\033[0m"  // 红色输出

/******************************************************************************************/
std::vector<cv::Point2f> getQRCodeCorners(const cv::Mat& image) {
    std::vector<cv::Point2f> corners;

    // 转换为ZXing图像格式
    ZXing::ImageView imageView{
            image.data,
            image.cols,
            image.rows,
            ZXing::ImageFormat::Lum
    };

    // 配置解码参数
    ZXing::DecodeHints hints;
    hints.setFormats(ZXing::BarcodeFormat::QRCode);
    hints.setTryRotate(true);
    hints.setTryHarder(true);

    // 检测二维码
    auto result = ZXing::ReadBarcode(imageView, hints);

    if (result.isValid())  {
        // 获取位置信息（新版API）
        const auto& position = result.position();

        // 提取四个角点（注意不同版本的API差异）
        corners.reserve(4);
        for (int i = 0; i < 4; ++i) {
            corners.emplace_back(
                    position[i].x,  // 左上->右上->右下->左下
                    position[i].y
            );
        }

        // 如果需要特定顺序（TL, TR, BR, BL），可以手动排序：
        std::sort(corners.begin(),  corners.end(),
                  [](const cv::Point2f& a, const cv::Point2f& b) {
                      return (a.x + a.y) < (b.x + b.y);
                  });
    }

    return corners;
}

/******************************************************************************************/

TEST(DefaultGrayScaleProcessorTest, GetGrayScaleArrayTest) {
    // 创建处理器实例
    CardProcessor processor;

    // 加载测试图像
    cv::Mat image = cv::imread("/home/starry/CLionProjects/cv_iims/rpc-service/cpp-module/test/img/test.png", cv::IMREAD_COLOR);

    ASSERT_FALSE(image.empty()) << RED_TEXT("picture load fail");

    // 调用方法
    auto [  msg,
            tcResult,
            grayValues,
            pc,
            pt,
            cValue,
            tValue,
            tcRatio]
            = processor.GetGrayScaleArray(image, 0, 0, 0, 0);

    // 断言结果
    EXPECT_GT(grayValues.size(), 0) << RED_TEXT("Gray values array is empty");
    EXPECT_GE(pc, 0) << RED_TEXT("First peak position is invalid");
    EXPECT_GE(pt, 0) << RED_TEXT("Second peak position is invalid");
    EXPECT_GT(cValue, 0.0) << RED_TEXT("cValue is invalid");
    EXPECT_GT(tValue, 0.0) << RED_TEXT("tValue is invalid");
    EXPECT_GT(tcRatio, 0.0) << RED_TEXT("tcRatio is invalid");
}

TEST(QRDetectorTest, qrDetectorTest){
    CardProcessor processor;

    // 加载测试图像
    cv::Mat image = cv::imread("/home/starry/CLionProjects/cv_iims/rpc-service/cpp-module/test/img/test.jpg", cv::IMREAD_COLOR);

    processor.GetTcResponseInfo(image, 0, 0, 0, 0);
}

TEST(ZxingTest, ZxingTest){
    cv::Mat image = cv::imread("/home/starry/CLionProjects/cv_iims/rpc-service/cpp-module/test/img/test.jpg",  cv::IMREAD_GRAYSCALE);

    auto corners = getQRCodeCorners(image);

    // 可视化
    cv::Mat colorImg;
    cv::cvtColor(image, colorImg, cv::COLOR_GRAY2BGR);

    for (size_t i = 0; i < corners.size();  ++i) {
        cv::line(colorImg, corners[i], corners[(i + 1) % 4],
                 cv::Scalar(0, 255, 0), 2);
        cv::circle(colorImg, corners[i], 5, cv::Scalar(0, 0, 255), -1);
    }

    cv::imshow("QR Code Corners", colorImg);
    cv::waitKey(0);
}

TEST(QRPickDetectorTest, qrPickDetectorTest){
    CardPickProcessor processor;

    // 加载测试图像
    cv::Mat image = cv::imread("/home/starry/CLionProjects/cv_iims/rpc-service/cpp-module/test/img/test_1.jpg", cv::IMREAD_COLOR);

    processor.GetTcResponseInfo(image, 0, 0, 0, 0);
}

TEST(QRPickDetectorTest, qrPickDetectorTest2){
    CardParamPickProcessor processor;

    // 加载测试图像
    cv::Mat image = cv::imread("/home/starry/CLionProjects/cv_iims/rpc-service/cpp-module/test/img/test_3.jpg", cv::IMREAD_COLOR);

    processor.GetTcResponseInfo(image, 0, 0, 0, 0);
}
